<template>
  <div class="IM">
    <!-- 聊天信息框 -->
    <div class="IM-body">
      <div class="centent">
        <div class="news-box" :class="userId == item.userId ? 'me' : ''" v-for="(item, index) in newsList" :key="index">
          <div class="user-info">
            <img class="img" :src="item.userAvatar" alt="" />
            <div class="role">({{ item.userRole }})</div>
            <div class="name">{{ item.userName }}</div>
            <div class="time">{{ item.time }}</div>
          </div>
          <div class="message">
            <span>
              {{ item.message }}
            </span>
          </div>
        </div>
      </div>
    </div>
    <!-- 禁用聊天的按钮 -->
    <!-- v-if="masterUserId == userId" -->
    <el-checkbox class="checkbox" @change="changeNoChat" v-model="noChat">禁言</el-checkbox>
    <!-- 您有新消息按钮 -->
    <div class="new-message">
      <img src="@/assets/img/trtc/icon-news.png" alt="" />
      <div>您有新消息</div>
    </div>
    <!-- 输入框 -->
    <el-row class="IM-input">
      <input type="text" v-if="masterUserId != userId" v-model="input" @keydown.enter="sendButton" :disabled="noChat" placeholder="说点什么" />
      <input type="text" v-else v-model="input" @keydown.enter="sendButton" placeholder="说点什么" />
      <button @click="sendButton">发送</button>
    </el-row>
  </div>
</template>

<script>
// 白板需要IM支持,需先登录IM,并且进入房间才能通信
// IM需要的参数
// SDKAppID:appid
// userId:用于登录IM
// userSig:用户登录IM
// groupID:加群(房间)使用,群(房间)id
import TIM from "tim-js-sdk";
import TIMUploadPlugin from "tim-upload-plugin";
import { mapGetters } from "vuex";
import UserAPI from "@/api/user";
import sendIM from "./sendIM";
const sdkAppId = 1400495479;
export default {
  props: {
    masterUserId: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      input: "",
      // groupID: "872924742", //im房间id 已经生成的房间id
      tim: null,
      newsList: [],
      noChat: false, //是否允许聊天
    };
  },
  computed: {
    ...mapGetters(["IMFn", "userInfo", "roomInfo", "IMStatus"]),
    userId() {
      return this.$store.state.userInfo.userId;
    },
    userSig() {
      return this.$store.state.userInfo.userSig;
    },
    groupID() {
      return String(this.$store.state.roomInfo.trtcRoomId);
    },
  },
  watch: {
    IMFn() {
      // 如果当前方法存在
      if (this[this.IMFn.name]) {
        this[this.IMFn.name](this.IMFn.data);
      }
    },
  },
  mounted() {
    this.newsList = [];
  },
  beforeDestroy() {
    // 退出群聊
    this.quitGroupPage();
  },
  destroyed() {
    // 退出登录,清空im
    this.logoutPage();
  },
  methods: {
    initTim() {
      // im初始化进行中
      this.$store.dispatch("setIMStatus_initialization", { isShow: true, status: 0 });
      let options = {
        SDKAppID: sdkAppId, // 接入时需要将其替换为您的即时通信 IM 应用的 SDKAppID
      };
      // 创建 SDK 实例，`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
      let tim = TIM.create(options); // SDK 实例通常用 tim 表示
      this.$store.dispatch("setIM", tim);
      this.tim = tim;
      window.TIM = TIM;
      // 设置 SDK 日志输出级别，详细分级请参见 <a href="https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/SDK.html#setLogLevel">setLogLevel 接口的说明</a>
      this.tim.setLogLevel(0); // 普通级别，日志量较多，接入时建议使用
      // tim.setLogLevel(1); // release 级别，SDK 输出关键信息，生产环境时建议使用
      // 注册腾讯云即时通信 IM 上传插件
      this.tim.registerPlugin({ "tim-upload-plugin": TIMUploadPlugin });
      // im初始化进行成功
      this.$store.dispatch("setIMStatus_initialization", { isShow: true, status: 1 });
      setTimeout(() => {
        // 如果im初始化状态不成立,或者等待中超过10秒
        if ((!this.IMStatus[0] || this.IMStatus[0].status != 1) && this.IMStatus[0].show) {
          this.$store.dispatch("setIMStatus_initialization", { isShow: true, status: 4 });
        }
      }, 10000);
      this.checkReady();
      this.IMLogin();
      this.monitor();
    },
    setIMStatusReady_2() {
      this.$store.dispatch("setIMStatus_ready", { isShow: true, status: 2 });
    },
    setIMStatusReady_1() {

      this.$store.dispatch("setIMStatus_ready", { isShow: true, status: 1 });
      if (this && this.joinGroup) {
        this.joinGroup();
      }
    },
    checkReady() {
      // sdk ready检测
      this.$store.dispatch("setIMStatus_ready", { isShow: true, status: 0 });

      // sdk处于 not_ready状态时
      this.tim.on(window.TIM.EVENT.SDK_NOT_READY, this.setIMStatusReady_2)
      this.tim.on(window.TIM.EVENT.SDK_READY, this.setIMStatusReady_1)
      setTimeout(() => {
        if ((!this.IMStatus[0] || this.IMStatus[0].status != 1) && this.IMStatus[0].show) {
          this.$store.dispatch("setIMStatus_ready", { isShow: true, status: 3 });
        }
      }, 10000);
    },
    // im登录
    IMLogin() {
      this.$store.dispatch("setIMStatus_login", { isShow: true, status: 0 });
      setTimeout(() => {
        // 如果im初始化状态不成立,或者等待中超过10秒
        if ((!this.IMStatus[2] || this.IMStatus[2].status != 1) && this.IMStatus[2].show) {
          this.$store.dispatch("setIMStatus_login", { isShow: true, status: 4 });
        }
      }, 10000);
      // 登录
      let promise = this.tim.login({
        userID: this.userId,
        userSig: this.userSig,
      });
      promise
        .then((imResponse) => {
          this.$store.dispatch("setIMStatus_login", { isShow: true, status: 1 });
          console.log("登陆成功:", imResponse.data); // 登录成功
        })
        .catch((imError) => {
          this.$store.dispatch("setIMStatus_login", { isShow: true, status: 2 });
          console.warn("登陆失败:", imError); // 登录失败的相关信息
        });


    },
    // im消息监听
    monitor() {
      // 2. 接收者通过监听 im 消息回调，将收到的数据添加到白板中
      this.tim.on(window.TIM.EVENT.MESSAGE_RECEIVED, this.clearData);
    },
    // clearData整理im接收到的数据
    clearData(event) {
      let messages = event.data;
      messages.forEach((message) => {
        console.log('输出message', message)
        // 群组消息
        if (message.conversationType === window.TIM.TYPES.CONV_GROUP) {
          // 如果是当前的白板群组
          if (message.to === this.groupID) {
            let elements = message.getElements();
            if (elements.length) {
              elements.forEach((element) => {
                if (element.type === "TIMCustomElem") {
                  if (element.content.extension === "TXWhiteBoardExt") {
                    if (message.from != this.userId) {
                      //   接收到白板消息,需要传输白板消息
                      this.$store.dispatch("setTEFn", {
                        name: "addSyncData",
                        data: element.content.data,
                      });
                    }
                  } else if (element.content.extension === "TRTCControl") {
                    // trtc控制消息
                    console.log("这是trtc的控制消息", element);
                    // 将收到的数据发送给TRTC页面,进行处理(比如静音某个用户,关闭摄像头等)
                    this.$emit("TRTCControl", element);
                  } else if (element.content.extension === "IMMessage") {
                    // Im聊天消息
                    console.log("这是IM聊天消息", element);
                    this.setNewsList(element.content, message.time);
                  } else if (element.content.extension === "IMControl") {
                    // IM控制消息
                    console.log("这是IM控制消息", element);
                    this.IMControl(element.content);
                  } else if (element.content.extension === "ROOMControl") {
                    // 房间控制信息,会议开始,会议暂停,会议结束
                    console.log("这是房间控制信息", element);
                    this.$store.dispatch("setTRTCFn", {
                      name: "IMroomControl",
                      data: element.content,
                    });
                  }
                }
              });
            }
          } else {
            // 其他群组消息忽略
          }
        }
      });
    },
    // 创建群组
    createGroup() {
      // 创建群组
      console.log("开始创建群组");
      let createGroup = this.tim.createGroup({
        type: window.TIM.TYPES.GRP_AVCHATROOM, //群类型
        name: "WebSDK",
        memberList: [
          {
            userID: "user1",
            // 群成员维度的自定义字段，默认情况是没有的，需要开通，详情请参阅自定义字段
            memberCustomField: [{ key: "group_member_test", value: "test" }],
          },
          {
            userID: "user2",
          },
        ], // 如果填写了 memberList，则必须填写 userID
      });
      console.log("开始创建群组2");
      createGroup
        .then(function (imResponse) {
          // 创建成功
          console.log("创建群成功", imResponse.data.group); // 创建的群的资料
        })
        .catch(function (imError) {
          console.warn("创建群失败", imError); // 创建群组失败的相关信息
        });
    },
    // 加入群组
    joinGroup() {
      console.log("加群中...");
      this.$store.dispatch("setIMStatus_join", { isShow: true, status: 0 });
      setTimeout(() => {
        // 如果im初始化状态不成立,或者等待中超过10秒
        if ((!this.IMStatus[3] || this.IMStatus[3].status != 1) && this.IMStatus[3].show) {
          this.$store.dispatch("setIMStatus_join", { isShow: true, status: 4 });
        }
      }, 10000);
      // 加入群组
      let pro = this.tim.joinGroup({
        groupID: this.groupID,
      });
      pro
        .then((imResponse) => {
          switch (imResponse.data.status) {
            case TIM.TYPES.JOIN_STATUS_WAIT_APPROVAL: // 等待管理员同意
              console.log("等待管理员同意");
              break;
            case TIM.TYPES.JOIN_STATUS_SUCCESS: // 加群成功
              this.$store.dispatch("setIMStatus_join", { isShow: true, status: 1 });
              this.joinBehindFn();
              console.log("加群成功", imResponse.data.group); // 加入的群组资料
              break;
            case TIM.TYPES.JOIN_STATUS_ALREADY_IN_GROUP: // 已经在群中
              this.$store.dispatch("setIMStatus_join", { isShow: true, status: 1 });
              this.joinBehindFn();
              // 向其他用户广播加群成功的消息
              console.log("您已经在群中");
              break;
            default:
              console.log("其他");
              break;
          }
        })
        .catch(function (imError) {
          console.log("加群失败", imError); // 申请加群失败的相关信息
          this.$store.dispatch("setIMStatus_join", { isShow: true, status: 2 });
        });
    },
    // joinBehindFn
    joinBehindFn() {
      // 向其他用户广播加群成功的消息
      let data = {
        data: this.userInfo,
        description: "updateUser",
        extension: "TRTCControl",
      };
      data.data = JSON.stringify(data.data);
      this.createCustomMessage({ data });
    },
    // 退出群组前向其他用户发送退出消息
    async quitGroupPage() {
      if (!this.tim) return;
      // 向其他用户广播退群的消息
      let data = {
        data: this.userInfo,
        description: "delUser",
        extension: "TRTCControl",
      };
      data.data = JSON.stringify(data.data);
      this.createCustomMessage({ data });
      console.log('发送退出消息成功')
    },
    // 退出登录
    async logoutPage() {
      await UserAPI.userLeaveRoom({ userId: this.userId });
      this.tim.quitGroup(this.groupID)
      this.tim.logout();
      this.offEvent();
      this.$store.dispatch("setIM", null);
      this.tim = null;
      window.TIM = null;
      console.log('退出IM(退出房间,退出登录,im清空)成功')
    },
    // 重新初始化ready的检测
    againReady() {
      this.offEvent();
      this.tim.logout();
      this.IMLogin();
      this.checkReady();
    },
    // 取消监听事件
    offEvent() {
      this.tim.off(window.TIM.EVENT.MESSAGE_RECEIVED, this.clearData);
      this.tim.off(window.TIM.EVENT.SDK_NOT_READY, this.setIMStatusReady_2);
      this.tim.off(window.TIM.EVENT.SDK_READY, this.setIMStatusReady_1);
    },
    // 获取用户群组
    getGroupList() {
      // 获取用户群组
      let getGroupList = this.tim.getGroupList();
      console.log(1);
      getGroupList
        .then(function (imResponse) {
          console.log("获取群组列表成功", imResponse.data.groupList); // 群组列表
          if (
            imResponse.data.groupList &&
            imResponse.data.groupList.length > 0
          ) {
            // 有群组时
            // this.groupID = imResponse.data.groupList[0].groupID;
            // this.joinGroup();
          } else {
            // 没有群组时调用创建群组方法
            // this.createGroup();
          }
        })
        .catch(function (imError) {
          console.log("获取群组列表失败:", imError); // 获取群组列表失败的相关信息
        });
    },
    // 白板页面创建消息,使用IM发送
    TECreateCustomMessage(TEInfo) {
      if (!this.tim) return;
      let message = this.tim.createCustomMessage({
        to: String(TEInfo.groupID), //白板房间id
        conversationType: window.TIM.TYPES.CONV_GROUP,
        payload: {
          data: JSON.stringify(TEInfo.data),
          description: "",
          extension: "TXWhiteBoardExt",
        },
      });
      this.sendMessage(message);
    },
    // 创建自定义控制信息(用于控制其他用户,比如主持人关闭其他用户音频,关闭其他用户视频)
    createCustomMessage(data) {
      console.log("创建的自定义消息,", data.data);
      if (!this.tim) return;
      let message = this.tim.createCustomMessage({
        to: data.id || this.groupID, //房间id,可先使用白板房间id
        conversationType: window.TIM.TYPES.CONV_GROUP,
        // payload: {
        //   data: "-1",
        //   description: "video",
        //   extension: "TRTCControl",
        // },
        payload: data.data,
      });
      this.sendMessage(message);
    },
    // 发送信息
    sendMessage(message) {
      this.tim.sendMessage(message).then(
        () => {
          // 同步成功
          console.log("同步成功");
        },
        (err) => {
          // 同步失败
          console.log("同步失败", err);
          // this.initTim();
        }
      );
    },
    // im聊天按钮发送
    sendButton() {
      // 如果没有数据
      if (!this.input) return;
      console.log(2);
      //  如果不允许聊天,并且还不是主持人
      if (this.noChat && this.masterUserId != this.userId) {
        return;
      }
      console.log(1);
      let time = new Date();
      let hours = time.getHours();
      hours < 10 ? (hours = "0" + hours) : hours;
      let minutes = time.getMinutes();
      minutes < 10 ? (minutes = "0" + minutes) : minutes;
      let seconds = time.getSeconds();
      seconds < 10 ? (seconds = "0" + seconds) : seconds;
      time = hours + ":" + minutes + ":" + seconds;

      let data = {
        userRole: "讲者",
        userId: this.userId,
        userName: this.userId,
        userAvatar:
          "https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3717120934,3932520698&fm=26&gp=0.jpg",
        message: this.input,
        time: time,
      };
      this.newsList.push(data);
      let payload = {
        data: {
          data: JSON.stringify(data),
          description: "",
          extension: "IMMessage",
        },
      };
      this.input = "";
      this.createCustomMessage(payload);
    },
    // 设置聊天消息
    setNewsList(content, time) {
      let data = content.data;
      console.log(data);
      if (!data) return;
      data = JSON.parse(data);
      console.log("设置消息");
      console.log(data);
      this.newsList.push(data);
      console.log(this.newsList);
    },
    // 设置全员禁言/解开禁言
    changeNoChat(value) {
      let payload = {
        data: {
          data: {
            has: "",
          },
          description: "imAll",
          extension: "IMControl",
        },
      };
      if (value) {
        // 禁言
        payload.data.data.has = "-1";
        payload.data.data = JSON.stringify(payload.data.data);
        this.createCustomMessage(payload);
      } else {
        // 解除禁言
        payload.data.data.has = "1";
        payload.data.data = JSON.stringify(payload.data.data);
        this.createCustomMessage(payload);
      }
    },
    // im的控制事件(一般用于禁言)
    IMControl(content) {
      if (content && content.data) {
        let data = JSON.parse(content.data);
        let description = content.description;
        // 对于聊天全员处理
        if (description == "imAll") {
          if (data.has == "-1") {
            // 全员禁言
            this.noChat = true;
          }
          if (data.has == "1") {
            // 全员解开禁言
            this.noChat = false;
          }
        }
      }
    },
  },
};
</script>

<style lang="scss">
.IM {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: relative;
}
.IM-body {
  // height: 33vw;
  flex: 1;
  order: 1;
  overflow: auto;
  flex-shrink: 1;
  background: #f5f5f5;
  .centent {
    .news-box {
      display: flex;
      flex-direction: column;
      margin: 10px 5px;
      &.me {
        .user-info {
          justify-content: flex-start;
          flex-direction: row-reverse;
        }
        .message {
          justify-content: flex-end;
          margin-right: 25px;
          span {
            color: #ffffff;
            background: rgb(116, 147, 240);
          }
        }
      }
      .user-info {
        display: flex;
        align-items: center;
        .time,
        .name,
        .role,
        .img {
          margin-left: 5px;
          font-size: 12px;
        }
        .name,
        .role {
          font-size: 11px;
          font-weight: 400;
          color: rgba(0, 0, 0, 0.65);
          line-height: 16px;
        }
        .name {
          margin-left: 7.5px;
        }
        .role {
          margin-right: 7.5px;
        }
        .time {
          font-size: 9px;
          font-weight: 400;
          color: rgba(0, 0, 0, 0.4);
          line-height: 13px;
        }
        .img {
          width: 16px;
          height: 16px;
          border-radius: 50%;
        }
      }
      .message {
        margin-top: 5px;
        margin-left: 25px;
        display: flex;
        span {
          background: #ffffff;
          font-size: 13px;
          padding: 5px;
          border-radius: 5px;
        }
      }
    }
  }
}
.checkbox {
  order: 2;
  margin-bottom: 15px;
  .el-checkbox__input {
    // .el-checkbox__inner {
    //   width: 16px;
    //   height: 16px;
    // }
    // .el-checkbox__inner::after{
    //   left: 8px;
    // }
  }
  .el-checkbox__label {
    padding-left: 8px;
  }
}
.IM-input {
  display: flex;
  //   height: 28px;
  order: 2;
  justify-content: space-between;
  input {
    box-sizing: border-box;
    flex: 1;
    height: 44px;
    background: #ffffff;
    border-radius: 2px;
    border: none;
    margin-right: 8px;
    padding: 8px 11px;
  }
  button {
    width: 78px;
    height: 44px;
    background: #475aa7;
    border-radius: 2px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    cursor: pointer;
    font-size: 18px;
    font-weight: 400;
    color: #ffffff;
    line-height: 25px;
  }
}
.new-message {
  position: absolute;
  cursor: pointer;
  right: -8px;
  bottom: 52px;
  box-sizing: border-box;
  height: 32px;
  background: rgba(255, 255, 255, 0.7);
  box-shadow: 0px 2px 4px 0px rgba(175, 175, 175, 0.16),
    0px 1px 10px 0px #ffffff;
  border-radius: 100px 0px 0px 100px;
  border: 1px solid #ffffff;

  display: flex;
  align-items: center;
  padding: 6px 15px 6px 7px;
  img {
    width: 21px;
    height: 21px;
    margin-right: 1px;
  }
  div {
    font-size: 14px;
    font-weight: 400;
    color: #475aa7;
    line-height: 20px;
    text-shadow: 0px 2px 4px rgba(175, 175, 175, 0.16);
  }
}
</style>
